home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Graphics Unleashed
/
PC Graphics Unleashed.iso
/
ch09
/
sweep.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-05
|
31KB
|
1,302 lines
/*
3D SWEEP OBJECT GENERATOR
by Alfonso Hermida
*/
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
#include <dos.h>
#include <dir.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#define ViewPort3D setviewport(0,0,getmaxy(),getmaxy(),1);
#define FullScreenViewPort setviewport(0,0,getmaxx(),getmaxy(),1);
#define DELAY delay(50);
#define TOL 0.0005
#define PI 3.14159265358979323846
#define LMB 1
#define RMB 2
#define MAXDATA 51
#define UP " \x1E"
#define DOWN " \x1F"
#define _NEW 0
#define _CREATE 1
#define _MOVE 2
#define _DELETE 3
#define _SNAP 4
#define _GRID 5
#define _V2D 7
#define _PREVIEW 8
#define _LOAD 9
#define _DXF 10
#define _POLYRAY 11
#define _DATA 12
#define _RAW 13
#define _GRIDDIVU 14
#define _GRIDDIVD 15
#define _SPLINEU 16
#define _SPLINED 17
#define _DELTAU 18
#define _DELTAD 19
#define _SEGSU 20
#define _SEGSD 21
#define _EXIT 22
#define IconNum 23
#define ESCkey 27
#define TEXT_INPUT 1
#define NUMBER_INPUT 0
typedef struct {
int x,y,width,height,color;
char str[81];
} Icon;
typedef struct {
float rmin, cmin,
rowstep,colstep;
int rows, cols;
} GRID;
typedef struct {
float x,y,z;
} POINT3D;
typedef struct {
int x,y;
} POINTint;
union REGS inregs;
union REGS outregs;
/* World Limits in 2D */
float WXleft;
float WXright;
float WYtop;
float WYbottom;
/* Device Limits */
int DXmin;
int DYmin;
int DYmax;
int DXmax;
/* Rotations for 3D View in Radians*/
float RX;
float RY;
float RZ;
float COSRX;
float SINRX;
float COSRY;
float SINRY;
float COSRZ;
float SINRZ;
/* Sweep Info */
float DeltaAngle;
float COSDA;
float SINDA;
int Segments;
int SplineSmooth;
GRID g;
int GridRowCol;
int GridStatus;
int SnapStatus;
int PBnum;
POINT3D PointBuffer[MAXDATA];
int DrawStatus;
void *BitMap;
char FileName[13], PolyrayFileName[13],
RAWFileName[13], DXFFileName[13];
int DXF, RAW;
FILE *DXFfptr, *RAWfptr;
void InitGraphics(void);
void ScreenToWorld2D(int x,int y,float *px, float *py);
void GetGridPoint2D(int mx,int my, float * wx, float * wy);
void UpdateMousePos(int xpos,int ypos,int status, int draw);
void UpdateGridStatus(void);
int IsMouse(void);
int MouseClick(void);
void MouseXY(int *xpos,int *ypos);
void MouseShow(int YesNo);
float DegToRad(float deg);
float RadToDeg(float rad);
POINT3D World3DToWorld2D(POINT3D p);
POINTint World2DToDevice(POINT3D p);
void drawpoint(POINT3D p1);
void drawline(POINT3D p1,POINT3D p2);
void drawgrid (void);
void drawaxis(void);
void SetAxesAngles(float rx, float ry, float rz);
void SweepData(void);
void DrawSpline(void);
void SweepALine(POINT3D pa, POINT3D pb);
Icon CreateIcon(int xo,int yo,int width,int height,
int color,char * text);
void DrawIcon(Icon ic);
int IconCheck(Icon ikon,int xm,int ym);
void CreateIconColumn(int xo,int yo,int width,int height,int color,
int spc, int num, Icon icon[],char **text);
void CreateIconRow(int xo,int yo,int width,int height,int color,
int spc, int num, Icon icon[],char **text);
void InitVariables(void);
int YesNoCMD(char *s);
void Redraw(void);
void DrawIconHiLite(Icon ic, int OnOff);
int SelectAPoint(int x, int y);
void ChangeParameter(int which, int UpDown);
void DisplayVars(void);
void Preview(void);
void LoadAFile(char *str);
void SaveAFile(char *str);
void AllocateInputBox(void);
void EraseInputBox(void);
char * InputBox(char *s);
char* KeyInput(char* str,int text);
char* prompt (int x,int y);
void SaveToPolyray(char * str);
void main()
{
int xpos, ypos, xposold=0, yposold=0, btn;
int i, j, QUIT=0, tmp, FLAG;
float wx, wy;
POINT3D p, pold;
char str[13];
Icon icon[IconNum]; // icon ID #:
char *str1[9] = {" New", // 0
" Create", // 1
" Move", // 2
" Delete", // 3
" Snap", // 4
" Grid", // 5
"", // 6
" 2D", // 7
" Preview"}; // 8
char *str2[5] = {" Load", // 9
" DXF", // 10
" Polyray", // 11
" Data", // 12
" Raw"}; // 13
char *str3[8] = {UP, // 14 Grid Divisions
DOWN, // 15
UP, // 16 Spline Smooth
DOWN, // 17
UP, // 18 Delta Angle
DOWN, // 19
UP, // 20 number of segments
DOWN}; // 21
InitGraphics();
if (!IsMouse()) {
closegraph();
printf("MOUSE driver not installed!");
exit(1);
}
setfillstyle(SOLID_FILL,LIGHTGRAY);
bar3d(getmaxy()+1,0,getmaxx(),getmaxy(),0,0);
CreateIconColumn(getmaxy()+10,50,70,15,LIGHTGRAY,5,9,icon,str1);
CreateIconColumn(getmaxy()+85,50,70,15,LIGHTGRAY,5,5,icon+9,str2);
CreateIconColumn(getmaxy()+10,240,24,15,LIGHTBLUE,5,8,icon+14,str3);
icon[22] = CreateIcon(getmaxy() + 45,getmaxy()-30,60,15,RED," QUIT");
for(i=0;i<IconNum;i++) if (i!=6) DrawIcon(icon[i]);
setcolor(BLACK);
outtextxy(icon[14].x + 70,(icon[14].y + icon[15].y)/2, "Grid");
outtextxy(icon[16].x + 70,(icon[16].y + icon[17].y)/2, "Spline");
outtextxy(icon[18].x + 70,(icon[18].y + icon[19].y)/2, "Angle");
outtextxy(icon[20].x + 70,(icon[20].y + icon[21].y)/2, "Segs");
setcolor(WHITE);
InitVariables();
drawaxis();
DisplayVars();
MouseShow(1);
do {
do {
MouseXY(&xpos,&ypos);
if((xpos != xposold) || (ypos != yposold))
UpdateMousePos(xpos,ypos,0,0);
xposold = xpos;
yposold = ypos;
btn = MouseClick();
}while(!btn);
if ((btn == LMB) && (xpos < getmaxy()) && DrawStatus)
UpdateMousePos(xpos,ypos,1,1);
for(i=0;i<IconNum;i++) {
if(IconCheck(icon[i],xpos,ypos)) {
switch(i) {
case _NEW :
DrawIconHiLite(icon[_NEW], 1);
if(YesNoCMD(" Delete All?")) InitVariables();
Redraw();
DrawIconHiLite(icon[_NEW], 0);
break;
case _CREATE :
if(DrawStatus) DrawStatus = 0;
else DrawStatus = 1;
DrawIconHiLite(icon[_CREATE], DrawStatus);
break;
case _MOVE :
DrawIconHiLite(icon[_MOVE], 1);
DrawStatus = 0;
DrawIconHiLite(icon[_CREATE], 0);
do {
MouseXY(&xpos,&ypos);
btn = MouseClick();
}while(!btn);
if (btn == LMB) {
tmp = SelectAPoint(xpos, ypos);
if(tmp != -1) {
ViewPort3D
FLAG = 0;
setwritemode(1);
xposold = xpos;
yposold = ypos;
setcolor(WHITE);
do {
MouseXY(&xpos,&ypos);
if((xposold != xpos) || (yposold != ypos)) {
if(!FLAG) {
MouseShow(0);
if (tmp > 0 && (tmp < PBnum))
drawline(PointBuffer[tmp],PointBuffer[tmp-1]);
if (tmp < PBnum - 1)
drawline(PointBuffer[tmp],PointBuffer[tmp+1]);
drawpoint(PointBuffer[tmp]);
MouseShow(1);
}
if(SnapStatus) GetGridPoint2D(xpos,ypos,&wx,&wy);
else ScreenToWorld2D(xpos,ypos,&wx, &wy);
p.x = wx;
p.y = wy;
p.z = 0.0;
MouseShow(0);
if (FLAG) {
if (tmp > 0 && (tmp < PBnum))
drawline(pold,PointBuffer[tmp-1]);
if (tmp < PBnum - 1)
drawline(pold,PointBuffer[tmp+1]);
}
if (tmp > 0 && (tmp < PBnum))
drawline(p,PointBuffer[tmp-1]);
if (tmp < PBnum - 1)
drawline(p,PointBuffer[tmp+1]);
MouseShow(1);
pold = p;
xposold = xpos;
yposold = ypos;
FLAG = 1;
}
btn = MouseClick();
}while(!btn);
if(btn == LMB) PointBuffer[tmp] = p;
setwritemode(0);
}
Redraw();
}
DrawIconHiLite(icon[_MOVE], 0);
break;
case _DELETE :
DrawIconHiLite(icon[_DELETE], 1);
DrawStatus = 0;
DrawIconHiLite(icon[_CREATE], 0);
do {
MouseXY(&xpos,&ypos);
btn = MouseClick();
}while(!btn);
if (btn == LMB) {
tmp = SelectAPoint(xpos, ypos);
if(tmp != -1) {
if (tmp == PBnum - 1)
PBnum--;
else {
for(j=tmp;j<PBnum-1;j++)
PointBuffer[j] = PointBuffer[j+1];
PBnum--;
}
}
Redraw();
}
DrawIconHiLite(icon[_DELETE], 0);
break;
case _SNAP :
if (SnapStatus) SnapStatus = 0;
else SnapStatus = 1;
DrawIconHiLite(icon[_SNAP], SnapStatus);
break;
case _GRID :
if (GridStatus) GridStatus = 0;
else GridStatus = 1;
Redraw();
DrawIconHiLite(icon[_GRID], GridStatus);
break;
case _V2D :
DrawIconHiLite(icon[_V2D], 1);
Redraw();
DrawIconHiLite(icon[_V2D], 0);
break;
case _PREVIEW :
DrawIconHiLite(icon[_PREVIEW], 1);
Preview();
DrawIconHiLite(icon[_PREVIEW], 0);
break;
case _LOAD : MouseShow(0);
strcpy(str,KeyInput("Load File:",TEXT_INPUT));
LoadAFile(str);
MouseShow(1);
Redraw();
break;
case _DXF : MouseShow(0);
sprintf(str,"Save As < %s >",DXFFileName);
strcpy(str,KeyInput(str,TEXT_INPUT));
if (strlen(str) == 0) strcpy(str,DXFFileName);
MouseShow(1);
DXF = 1;
if ((DXFfptr = fopen(str,"w+t")) != NULL) {
Preview();
fclose(DXFfptr);
strcpy(DXFFileName,str);
}
DXF = 0;
break;
case _POLYRAY : MouseShow(0);
sprintf(str,"Save As < %s >",PolyrayFileName);
strcpy(str,KeyInput(str,TEXT_INPUT));
if (strlen(str) == 0) strcpy(str,PolyrayFileName);
MouseShow(1);
SaveToPolyray(str);
break;
case _DATA : MouseShow(0);
sprintf(str,"Save As < %s >",FileName);
strcpy(str,KeyInput(str,TEXT_INPUT));
if (strlen(str) == 0) strcpy(str,FileName);
MouseShow(1);
SaveAFile(str);
break;
case _RAW : MouseShow(0);
sprintf(str,"Save As < %s >",RAWFileName);
strcpy(str,KeyInput(str,TEXT_INPUT));
if (strlen(str) == 0) strcpy(str,RAWFileName);
MouseShow(1);
RAW = 1;
if ((RAWfptr = fopen(str,"w+t")) != NULL) {
Preview();
fclose(RAWfptr);
strcpy(RAWFileName,str);
}
RAW = 0;
break;
case _GRIDDIVU: ChangeParameter(_GRIDDIVU, 1);
Redraw();break;
case _GRIDDIVD: ChangeParameter(_GRIDDIVD, 0);
Redraw();break;
case _SPLINEU : ChangeParameter(_SPLINEU, 1);
Preview();break;
case _SPLINED : ChangeParameter(_SPLINED, 0);
Preview();break;
case _DELTAU : ChangeParameter(_DELTAU, 1);
Preview();break;
case _DELTAD : ChangeParameter(_DELTAD, 0);
Preview();break;
case _SEGSU : ChangeParameter(_SEGSU, 1);
Preview();break;
case _SEGSD : ChangeParameter(_SEGSD, 0);
Preview();break;
case _EXIT :
DrawIconHiLite(icon[_EXIT], 1);
if(YesNoCMD(" Quit?")) QUIT = 1;
else Redraw();
DrawIconHiLite(icon[_EXIT], 0);
break;
}
}
}
}while(btn != QUIT);
closegraph();
}
/* /////////////////////////////////////////////////////// */
void SaveToPolyray(char * str) {
FILE *fptr;
int i=1;
char s[40];
strcpy(PolyrayFileName,str);
sprintf(s,"Overwrite < %s > ?",str);
if ((fptr = fopen(str,"r")) != NULL) i = YesNoCMD(s);
fclose(fptr);
if (i) {
if ((fptr = fopen(str,"w+t")) == NULL) {
printf("\7");
Redraw();
}
else {
if(PBnum) {
fprintf(fptr,"object {\n");
fprintf(fptr," lathe 2, <0, 1, 0>, %d,\n",PBnum);
for(i=0;i<PBnum;i++) {
fprintf(fptr," <%g, %g, %g>",PointBuffer[i].x,
PointBuffer[i].y,
PointBuffer[i].z);
if(i<PBnum-1)
fprintf(fptr,",\n");
else
fprintf(fptr,"\n shiny_red\n}");
}
fclose(fptr);
}
}
}
Redraw();
}
void AllocateInputBox(void)
{
unsigned size;
size = imagesize(100,100,400,200);
if ((BitMap = (void *)malloc(size)) == NULL)
{
printf("Not enough memory to allocate buffer!\n");
exit(1);
}
MouseShow(0);
getimage(100,100,400,200,BitMap);
MouseShow(1);
}
void EraseInputBox(void)
{
MouseShow(0);
putimage(100,100,BitMap,COPY_PUT);
free(BitMap);
MouseShow(1);
}
char * InputBox(char *s)
{
static char ans[80];
MouseShow(0);
AllocateInputBox();
setfillstyle(1,LIGHTGRAY);
bar3d(100,100,400,200,0,0);
setcolor(15);
rectangle(100,100,400,200);
rectangle(105,200-2*textheight("W")-5,395,195);
setcolor(0);
outtextxy(105,105,s);
MouseShow(1);
strcpy(ans,prompt(107,200-2*textheight("W")-3));
MouseShow(0);
EraseInputBox();
MouseShow(1);
return(ans);
}
char* KeyInput(char* str,int text)
{
static char str1[80];
int i,error;
do
{
error = 0;
strcpy(str1,InputBox(str));
if (text==0)
{
for (i=0;i<strlen(str1);i++)
if ((!isdigit(str1[i])) && (str1[i] != '.')
&& (toupper(str1[i]) != 'E') && (str1[i] != '-'))
error = 1;
}
else {
for (i=0;i<strlen(str1);i++)
if (str1[i] == ' ') error = 1;
}
}while(error);
return (str1);
}
char* prompt (int x,int y)
{
char KeyChar,key[2];
static char word[80];
int j, erase, stop,TW = textwidth("W"),TH = textheight("W")+1;
j = 0;
setcolor(0);
erase = stop = 0;
key[1] = '\0';
do
{
KeyChar = getch();
key[0] = KeyChar;
if (KeyChar == 13) stop = 1;
if ((KeyChar == 8) && (j > 0)) erase = 1;
if (KeyChar == 0) {
KeyChar = getch();
if (((KeyChar == 75) || (KeyChar == 83)) && (j > 0)) erase = 1;
}
if (stop) word[j] = '\0';
else
if (erase) {
if (j) {
j --;
MouseShow(0);
bar(x+TW*j,y,x+TW*(j+2),y+TH);
outtextxy(x+TW*j,y,"_");
MouseShow(1);
}
erase = 0;
}
else {
if(j<34) {
MouseShow(0);
bar(x+TW*j,y,x+TW*(j+2),y+TH);
outtextxy(x+TW*j,y,key);
outtextxy(x+TW*(j+1),y,"_");
MouseShow(1);
word[j] = key[0];
j++;
}
}
}while(!stop);
return(word);
}
void SaveAFile(char *str)
{
FILE *fptr;
int i=1;
char s[40];
sprintf(s,"Overwrite < %s > ?",str);
if ((fptr = fopen(str,"r")) != NULL) i = YesNoCMD(s);
fclose(fptr);
if (i) {
if ((fptr = fopen(str,"w+t")) == NULL) {
printf("\7");
Redraw();
}
else {
if(PBnum) {
for(i=0;i<PBnum;i++)
fprintf(fptr,"%g %g %g\n",PointBuffer[i].x,
PointBuffer[i].y,
PointBuffer[i].z);
fclose(fptr);
}
}
}
Redraw();
}
void LoadAFile(char *str)
{
FILE *fptr;
float x,y,z,r,s;
int bnum;
if ( (fptr = fopen(str,"r")) == NULL) {
printf("\7");
Redraw();
}
else {
bnum = -1;
while (!feof(fptr)) {
if ((fscanf(fptr,"%f",&x) > 0) &&
(fscanf(fptr,"%f",&y) > 0) &&
(fscanf(fptr,"%f",&z) > 0)) {
bnum++;
PointBuffer[bnum].x = x;
PointBuffer[bnum].y = y;
PointBuffer[bnum].z = z;
}
}
fclose(fptr);
strcpy(FileName,str);
PBnum = bnum+1;
}
}
void Preview(void) {
MouseShow(0);
SetAxesAngles(20, -15, -5);
ViewPort3D
clearviewport();
drawaxis();
MouseShow(1);
DrawSpline();
}
void ChangeParameter(int which, int UpDown) {
switch(which) {
case _GRIDDIVU:
case _GRIDDIVD:
if (UpDown && GridRowCol < 100) GridRowCol+=2;
else if (!UpDown && GridRowCol > 10) GridRowCol-=2;
break;
case _SPLINEU :
case _SPLINED :
if (UpDown && SplineSmooth < 10) SplineSmooth++;
else if (!UpDown && SplineSmooth > 1) SplineSmooth--;
break;
case _DELTAU :
case _DELTAD :
if (UpDown && DeltaAngle < 90) DeltaAngle += 15;
else if (!UpDown && DeltaAngle > 15) DeltaAngle -= 15;
COSDA = cos(DegToRad(DeltaAngle));
SINDA = sin(DegToRad(DeltaAngle));
break;
case _SEGSU :
case _SEGSD :
if (UpDown && Segments < 24) Segments++ ;
else if (!UpDown && Segments > 1) Segments--;
break;
}
DisplayVars();
}
void DisplayVars(void) {
char s[80];
FullScreenViewPort
MouseShow(0);
setcolor(LIGHTGRAY);
setfillstyle(SOLID_FILL,LIGHTGRAY);
bar3d(getmaxy()+40,245,getmaxy()+70,390,0,0);
setcolor(BLACK);
sprintf(s,"%d",GridRowCol);
outtextxy(getmaxy()+40,250,s);
sprintf(s,"%d",SplineSmooth);
outtextxy(getmaxy()+40,250+45,s);
sprintf(s,"%d",(int)DeltaAngle);
outtextxy(getmaxy()+40,250+85,s);
sprintf(s,"%d",Segments);
outtextxy(getmaxy()+40,250+125,s);
setcolor(WHITE);
MouseShow(1);
}
int SelectAPoint(int x, int y) {
float wx, wy, dist1, dist2=3.4e38;
int i, pnt=-1;
ScreenToWorld2D(x,y,&wx, &wy);
if(!PBnum) return(-1);
for(i=0;i<PBnum;i++) {
dist1 = (wx - PointBuffer[i].x)*(wx - PointBuffer[i].x) +
(wy - PointBuffer[i].y)*(wy - PointBuffer[i].y);
if(dist1 < dist2) {
dist2 = dist1;
pnt = i;
}
}
return(pnt);
}
void DrawIconHiLite(Icon ic, int OnOff)
{
int color;
color = getcolor();
FullScreenViewPort
if (OnOff) {
MouseShow(0);
setcolor(WHITE);
rectangle(ic.x+1,ic.y+1,ic.x+ic.width-1,ic.y+ic.height-1);
setcolor(BLACK);
line(ic.x,ic.y,ic.x+ic.width,ic.y);
line(ic.x,ic.y,ic.x,ic.y+ic.height);
line(ic.x+1,ic.y+1,ic.x+ic.width-1,ic.y+1);
line(ic.x+1,ic.y+1,ic.x+1,ic.y+ic.height-1);
MouseShow(1);
}
else {
MouseShow(0);
setcolor(BLACK);
rectangle(ic.x+1,ic.y+1,ic.x+ic.width-1,ic.y+ic.height-1);
setcolor(WHITE);
line(ic.x,ic.y,ic.x+ic.width,ic.y);
line(ic.x,ic.y,ic.x,ic.y+ic.height);
line(ic.x+1,ic.y+1,ic.x+ic.width-1,ic.y+1);
line(ic.x+1,ic.y+1,ic.x+1,ic.y+ic.height-1);
MouseShow(1);
setcolor(color);
}
}
void Redraw(void) {
int i;
MouseShow(0);
ViewPort3D
clearviewport();
SetAxesAngles(0, 0, 0);
if (GridStatus) {
UpdateGridStatus();
drawgrid();
}
drawaxis();
if (PBnum > 0)
drawpoint(PointBuffer[0]);
for(i=1;i<PBnum;i++) {
drawpoint(PointBuffer[i]);
drawline(PointBuffer[i],PointBuffer[i-1]);
}
MouseShow(1);
}
int YesNoCMD(char *s)
{
char *str[2] = {" Yes"," No"};
Icon icon[2];
int i,xpos,ypos,status,choice = 0;
FullScreenViewPort
CreateIconRow(180,200,55,15,LIGHTGRAY,60,2,icon,str);
MouseShow(0);
setfillstyle(1,LIGHTGRAY);
bar3d(150,150,400,220,0,0);
for(i=0;i<2;i++) DrawIcon(icon[i]);
setcolor(BLACK);
outtextxy(160,160,s);
setcolor(WHITE);
outtextxy(161,161,s);
MouseShow(1);
do { MouseXY(&xpos, &ypos); }while(!MouseClick());
for(i=0;i<2;i++) {
status = IconCheck(icon[i],xpos,ypos);
if (status) {
switch(i) {
case 0: choice = 1;break;
case 1: choice = 0;break;
}
}
}
return(choice);
}
void InitVariables(void) {
WXleft = -1;
WXright = 1;
WYtop = 1;
WYbottom = -1;
DXmin = 0.0;
DYmin = 0.0;
DYmax = getmaxy();
DXmax = getmaxy();
SetAxesAngles(0, 0, 0);
DrawStatus = 0;
GridRowCol = 40;
GridStatus = 0;
UpdateGridStatus();
SnapStatus = 0;
PBnum = 0;
SplineSmooth = 5;
DeltaAngle = 30;
COSDA = cos(DegToRad(DeltaAngle));
SINDA = sin(DegToRad(DeltaAngle));
Segments = 12;
strcpy(FileName,"");
strcpy(PolyrayFileName,"");
strcpy(RAWFileName,"");
strcpy(DXFFileName,"");
DXF = 0;
RAW = 0;
}
Icon CreateIcon(int xo,int yo,int width,int height,int color,char * text)
{
Icon temp;
temp.x = xo;
temp.y = yo;
temp.width = width;
temp.height = height;
temp.color = color;
strcpy(temp.str,text);
return(temp);
}
void CreateIconColumn(int xo,int yo,int width,int height,int color,
int spc, int num, Icon icon[],char **text)
{
int i,y;
y = yo;
for(i=0;i<num;i++) {
icon[i] = CreateIcon(xo,y,width,height,color,text[i]);
y += height + spc;
}
}
void CreateIconRow(int xo,int yo,int width,int height,int color,
int spc, int num, Icon icon[],char **text)
{
int i,x;
x = xo;
for(i=0;i<num;i++) {
icon[i] = CreateIcon(x,yo,width,height,color,text[i]);
x += width + spc;
}
}
void DrawIcon(Icon ic)
{
int color;
color = getcolor();
MouseShow(0);
setcolor(0);
setfillstyle(1,ic.color);
bar3d(ic.x,ic.y,ic.x+ic.width,ic.y+ic.height,0,0);
rectangle(ic.x,ic.y,ic.x+ic.width,ic.y+ic.height);
rectangle(ic.x+1,ic.y+1,ic.x+ic.width-1,ic.y+ic.height-1);
outtextxy(ic.x+3,ic.y + 5,ic.str);
setcolor(15);
line(ic.x,ic.y,ic.x+ic.width,ic.y);
line(ic.x,ic.y,ic.x,ic.y+ic.height);
line(ic.x+1,ic.y+1,ic.x+ic.width-1,ic.y+1);
line(ic.x+1,ic.y+1,ic.x+1,ic.y+ic.height-1);
outtextxy(ic.x+2,ic.y + 4,ic.str);
MouseShow(1);
setcolor(color);
}
int IconCheck(Icon ikon,int xm,int ym)
{
if ((xm > ikon.x) && (xm < ikon.x + ikon.width) &&
(ym > ikon.y) && (ym < ikon.y + ikon.height))
return(1);
else return(0);
}
void DrawSpline(void) {
float ax, ay, az, bx, by, bz,cx, cy, cz, dx, dy, dz;
float S1x, S1y, S1z, S2x, S2y, S2z, t, tt, ttt;
POINT3D T[MAXDATA+3], p1, p2;
int i,j, k;
if(PBnum) {
if (DXF) fprintf (DXFfptr,"0\nSECTION\n2\nENTITIES\n");
for (i=1;i<PBnum+1;i++) T[i] = PointBuffer[i-1];
T[0] = T[1];
T[PBnum+1] = T[PBnum];
T[PBnum+2] = T[PBnum];
for(j = 1;j<=PBnum-1;j++) {
// components of slope at point j
S1x = T[j + 1].x - T[j - 1].x;
S1y = T[j + 1].y - T[j - 1].y;
S1z = T[j + 1].z - T[j - 1].z;
// component of slopes at point j+1
S2x = T[j + 2].x - T[j].x;
S2y = T[j + 2].y - T[j].y;
S2z = T[j + 2].z - T[j].z;
// calc ax, bx, cx, dx based on cubic spline definition
// most of this is not used since point j is located at t = 0
// where 0<=t<=1 using {a}t^3 + {b}t^2 + {c}t + {d} -> Cubic Spline
//
// | a | | 2 -2 1 1 | | x(0) | <- initial point
// | b | = | -3 3 -2 -1 | | x(1) | <- ending point
// | c | | 0 0 1 0 | | x'(0) | <- initial slope
// | d | | 1 0 0 0 | | x'(1) | <- ending slope
ax = 2 * T[j].x - 2 * T[j + 1].x + S1x + S2x;
bx = -3 * T[j].x + 3 * T[j + 1].x - 2 * S1x - S2x;
cx = S1x;
dx = T[j].x;
ay = 2 * T[j].y - 2 * T[j + 1].y + S1y + S2y;
by = -3 * T[j].y + 3 * T[j + 1].y - 2 * S1y - S2y;
cy = S1y;
dy = T[j].y;
az = 2 * T[j].z - 2 * T[j + 1].z + S1z + S2z;
bz = -3 * T[j].z + 3 * T[j + 1].z - 2 * S1z - S2z;
cz = S1z;
dz = T[j].z;
for(k=0;k<SplineSmooth + 1;k++) {
t = k/(float)SplineSmooth;
tt = t*t;
ttt = tt *t;
p1.x = ax * ttt + bx * tt + cx * t + dx;
p1.y = ay * ttt + by * tt + cy * t + dy;
p1.z = az * ttt + bz * tt + cz * t + dz;
if (k==0) p2 = p1;
else {
SweepALine(p1, p2);
p2 = p1;
}
}
}
if (DXF) fprintf (DXFfptr,"0\nENDSEC\n0\nEOF\n");
}
}
void SweepALine(POINT3D pa, POINT3D pb) {
POINT3D p1,p2,p3,p4;
int i, j;
MouseShow(0);
p1 = pa;
p2 = pb;
for (j=0;j<Segments;j++) {
p3.x = COSDA*p1.x + SINDA*p1.z;
p3.y = p1.y;
p3.z = -SINDA*p1.x + COSDA*p1.z;
p4.x = COSDA*p2.x + SINDA*p2.z;
p4.y = p2.y;
p4.z = -SINDA*p2.x + COSDA*p2.z;
if (DXF) {
fprintf(DXFfptr,"0\n3DFACE\n10\n%g\n20\n%g\n30\n%g\n",p1.x,p1.y,p1.z);
fprintf(DXFfptr, "11\n%g\n21\n%g\n31\n%g\n",p2.x,p2.y,p2.z);
fprintf(DXFfptr, "12\n%g\n22\n%g\n32\n%g\n",p4.x,p4.y,p4.z);
fprintf(DXFfptr, "13\n%g\n23\n%g\n33\n%g\n",p3.x,p3.y,p3.z);
}
if (RAW) {
fprintf(RAWfptr,"%g %g %g %g %g %g %g %g %g\n",p1.x,p1.y,p1.z,
p2.x,p2.y,p2.z,
p3.x,p3.y,p3.z);
fprintf(RAWfptr,"%g %g %g %g %g %g %g %g %g\n",p2.x,p2.y,p2.z,
p4.x,p4.y,p4.z,
p3.x,p3.y,p3.z);
}
drawline(p1,p2);
drawline(p3,p4);
drawline(p1,p3);
drawline(p2,p4);
p1 = p3;
p2 = p4;
}
MouseShow(1);
}
void SweepData(void) {
POINT3D p1,p2,p3,p4;
int i, j;
MouseShow(0);
for(i=0;i<PBnum-1;i++) {
p1 = PointBuffer[i];
p2 = PointBuffer[i+1];
for (j=0;j<Segments;j++) {
p3.x = COSDA*p1.x + SINDA*p1.z;
p3.y = p1.y;
p3.z = -SINDA*p1.x + COSDA*p1.z;
p4.x = COSDA*p2.x + SINDA*p2.z;
p4.y = p2.y;
p4.z = -SINDA*p2.x + COSDA*p2.z;
drawline(p1,p2);
drawline(p3,p4);
drawline(p1,p3);
drawline(p2,p4);
p1 = p3;
p2 = p4;
}
}
MouseShow(1);
}
void InitGraphics(void)
{
int gdriver = DETECT, gmode, errorcode;
initgraph(&gdriver, &gmode, "");
if (gdriver != VGA) {
printf("VGA graphics card required.\n");
exit(1);
}
errorcode = graphresult();
if (errorcode != grOk) /* an error occurred */
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1); /* terminate with an error code */
}
setviewport(0,0,getmaxx(),getmaxy(),1);
}
float DegToRad(float deg)
{
return(deg*PI/180.0);
}
float RadToDeg(float rad)
{
return(rad*180.0/PI);
}
void SetAxesAngles(float rx, float ry, float rz) {
RX = DegToRad(rx);
RY = DegToRad(ry);
RZ = DegToRad(rz);
COSRX = cos(RX);
SINRX = sin(RX);
COSRY = cos(RY);
SINRY = sin(RY);
COSRZ = cos(RZ);
SINRZ = sin(RZ);
}
void drawgrid (void)
{
int j;
float rmax,cmax;
POINT3D p1,p2;
rmax = g.rmin+g.rowstep*(g.rows);
cmax = g.cmin+g.colstep*(g.cols);
setcolor(LIGHTGRAY);
for (j=0;j<g.cols+1;j++) {
p1.x = g.cmin+j*g.colstep;
p1.y = rmax;
p1.z = 0.0;
p2.x = g.cmin+j*g.colstep;
p2.y = g.rmin,
p2.z = 0.0;
drawline(p1,p2);
}
for (j=0;j<g.rows+1;j++) {
p1.x = g.cmin;
p1.y = g.rmin+j*g.rowstep;
p1.z = 0.0;
p2.x = cmax;
p2.y = g.rmin+j*g.rowstep;
p2.z = 0.0;
drawline(p1,p2);
}
setcolor(WHITE);
}
void drawaxis(void)
{
/* draw 3D axis */
POINT3D orig,px,py,pz;
POINTint p;
orig.x = orig.y = orig.z = 0.0;
px.x = 0.7*WXright;
px.y = px.z = 0.0;
py.x = py.z = 0.0;
py.y = 0.7*WXright;
pz.x = pz.y = 0.0;
pz.z = 0.7*WXright;
setlinestyle(SOLID_LINE,1,3);
setcolor(4);
drawline(orig,px);
setcolor(2);
drawline(orig,py);
setcolor(1);
drawline(orig,pz);
setlinestyle(SOLID_LINE,1,1);
setcolor(15);
}
POINT3D World3DToWorld2D(POINT3D p)
{
POINT3D ptemp;
ptemp = p;
if (RX) {
ptemp.x = p.x;
ptemp.y = COSRX*p.y - SINRX*p.z;
ptemp.z = SINRX*p.y + COSRX*p.z;
p = ptemp;
}
if (RY) {
ptemp.x = COSRY*p.x + SINRY*p.z;
ptemp.y = p.y;
ptemp.z = -SINRY*p.x + COSRY*p.z;
p = ptemp;
}
if (RZ) {
ptemp.x = COSRZ*p.x - SINRZ*p.y;
ptemp.y = SINRZ*p.x + COSRZ*p.y;
ptemp.z = p.z;
}
if (fabs(ptemp.x) < TOL) ptemp.x = 0.0;
if (fabs(ptemp.y) < TOL) ptemp.y = 0.0;
if (fabs(ptemp.z) < TOL) ptemp.z = 0.0;
return(ptemp);
}
POINTint World2DToDevice(POINT3D p)
{
POINTint ptemp;
ptemp.x = (WXleft-p.x)*(DXmax-DXmin)/(WXleft-WXright) + DXmin + 0.5;
ptemp.y = (WYtop-p.y)*(DYmax-DYmin)/(WYtop-WYbottom) + DYmin + 0.5;
return(ptemp);
}
void drawpoint(POINT3D p1)
{
/* draws a 3D point */
POINTint p2;
p1.z = -p1.z;
p2 = World2DToDevice(World3DToWorld2D(p1));
//circle(p2.x,p2.y,2);
rectangle(p2.x - 2, p2.y - 2, p2.x + 2, p2.y + 2);
}
void drawline(POINT3D p1,POINT3D p2)
{
/* draws a 3D line */
POINTint p11,p22;
p1.z = -p1.z;
p2.z = -p2.z;
p11 = World2DToDevice(World3DToWorld2D(p1));
p22 = World2DToDevice(World3DToWorld2D(p2));
line(p11.x,p11.y,p22.x,p22.y);
}
void ScreenToWorld2D(int x,int y,float *px, float *py)
{
*px = (DXmin - x)*(WXleft - WXright) / (DXmax - DXmin) + WXleft;
*py = (DYmin - y)*(WYtop - WYbottom) / (DYmax - DYmin) + WYtop ;
}
void GetGridPoint2D(int mx,int my, float * wx, float * wy)
{
int nx,ny;
ScreenToWorld2D(mx,my,wx,wy);
nx = (*wx - g.cmin) / (float)g.colstep + .5;
ny = (*wy - g.rmin) / (float)g.rowstep + .5;
*wx = g.cmin + nx * g.colstep;
*wy = g.rmin + ny * g.rowstep;
}
void UpdateMousePos(int xpos,int ypos,int status, int draw)
{
int i,j;
float wx,wy;
char s[80];
UpdateGridStatus();
if(SnapStatus == 0)
ScreenToWorld2D(xpos,ypos,&wx,&wy);
else
GetGridPoint2D(xpos,ypos,&wx,&wy);
if (fabs(wx) < TOL) wx = 0.0;
if (fabs(wy) < TOL) wy = 0.0;
setcolor(15);
setfillstyle(1,WHITE);
bar3d(getmaxy()+15, 3,getmaxx(),18,0,0);
bar3d(getmaxy()+15,25,getmaxx(),40,0,0);
setcolor(0);
sprintf(s,"%g",wx);
outtextxy(getmaxy()+17,5,s);
sprintf(s,"%g",wy);
outtextxy(getmaxy()+17,28,s);
if (status && (PBnum < MAXDATA)) {
PointBuffer[PBnum].x = wx;
PointBuffer[PBnum].y = wy;
PointBuffer[PBnum].z = 0.0;
setcolor(15);
MouseShow(0);
ViewPort3D
drawpoint(PointBuffer[PBnum]);
if (PBnum > 0 && draw) drawline(PointBuffer[PBnum],PointBuffer[PBnum-1]);
MouseShow(1);
FullScreenViewPort
PBnum++;
}
}
void UpdateGridStatus(void)
{
g.rmin = WXleft;
g.cmin = WYbottom;
g.rowstep = (fabs(WYbottom)+ fabs(WYtop)) / (float)GridRowCol;
g.colstep = (fabs(WXleft)+ fabs(WXright)) / (float)GridRowCol;
g.rows = GridRowCol;
g.cols = GridRowCol;
}
int IsMouse(void)
{
inregs.x.ax = 0;
int86(0x33,&inregs,&outregs);
return(outregs.x.ax ? outregs.x.bx : 0);
}
int MouseClick(void)
{
int click = 0;
inregs.x.ax = 5;
inregs.x.bx = 1;
int86(0x33,&inregs,&outregs);
click = outregs.x.bx << 1;
inregs.x.bx--;
int86(0x33,&inregs,&outregs);
return(click | outregs.x.bx);
}
void MouseXY(int *xpos,int *ypos)
{
inregs.x.ax = 3;
int86(0x33,&inregs,&outregs);
*xpos = outregs.x.cx;
*ypos = outregs.x.dx;
}
void MouseShow(int YesNo)
{
if (YesNo) inregs.x.ax = 1;
else inregs.x.ax = 2;
int86(0x33,&inregs,&outregs);
}